<?php

namespace App\Http\Controllers;

use App\Exceptions\AppException;
use App\Libs\Sms\Sms;
use App\Models\District;
use App\Models\User;
use App\Services\UserService;
use Illuminate\Database\Query\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rule;
use Spatie\Permission\Models\Role;

class UserController extends Controller
{
    public function test()
    {
        return responder()->success();
    }

    /**
     * 用户登录
     */
    public function login(Request $request)
    {
        $request->validate([
            'phone' => 'required|regex:/^1[3456789]\d{9}$/',
            'password' => 'required',
            'captcha' => 'required|captcha_api:' . request('key') . ',math',
        ], [
            'captcha.required' => '验证码不能为空',
            'captcha.captcha_api' => '验证码不正确',
        ]);

        $user = User::where('phone', $request->phone)->first();
        if (!$user || !Hash::check($request->password, $user->password)) {
            throw new AppException('用户名或密码不正确');
        }

        $response = UserService::detail($user);
        $response['token'] = $user->createToken('SanctumAuth')->plainTextToken;

        return responder()->success($response);
    }

    /**
     * 创建用户
     */
    public function create(Request $request)
    {
        $request->validate([
            'name' => ['required'],
            'phone' => ['required', 'regex:/^1[3456789]\d{9}$/', 'unique:users,phone'],
            'email' => ['email', 'unique:users,email'],
            'district_id' => ['required', 'exists:districts,id,deleted_at,NULL'],
            'password' => ['required', 'min:6'],
            'password_confirmation' => ['required', 'same:password'],
            'role_names' => ['required'],
        ], [
            'name.required' => '员工姓名不能为空',
            'phone.required' => '手机号不能为空',
            'phone.regex' => '手机号不正确',
            'phone.unique' => '手机号已经存在',
            'email.email' => 'email不正确',
            'email.unique' => 'email已经存在',
            'district_id.required' => '所属区县不能为空',
            'district_id.exists' => '所属区县不正确',
            'password.required' => '密码不能为空',
            'password.min' => '密码不能少于6位',
            'password_confirmation.required' => '确认密码不能为空',
            'password_confirmation.same' => '两次密码不一致',
            'role_names.required' => '角色不能为空',
        ]);

        $this->checkRole($request->district_id, $request->role_names);

        $model = new User();
        $model->name = $request->name;
        $model->phone = $request->phone;
        $model->email = !empty($request->email) ? $request->email : '';
        $model->district_id = $request->district_id;
        $model->password = bcrypt($request->password);

        DB::beginTransaction();
        try {
            $model->save();
            $model->syncRoles($request->role_names);
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }

        $response = UserService::detail($model);
        return responder()->success($response);
    }

    /**
     * 编辑用户
     */
    public function update(Request $request)
    {
        $request->validate([
            'id' => ['required', 'exists:users,id'],
            'name' => ['required'],
            'phone' => ['required', 'regex:/^1[3456789]\d{9}$/', Rule::unique('users', 'phone')->ignore($request->id)],
            'email' => ['email', Rule::unique('users', 'email')->ignore($request->id)],
            'district_id' => ['required', 'exists:districts,id,deleted_at,NULL'],
            'password' => ['min:6'],
            'password_confirmation' => ['required_with:password', 'same:password'],
            'role_names' => ['required'],
        ]);

        $this->checkRole($request->district_id, $request->role_names);

        $model = User::where(['id' => $request->id])->first();
        $model->name = $request->name;
        $model->phone = $request->phone;
        $model->email = !empty($request->email) ? $request->email : '';
        $model->district_id = $request->district_id;
        !empty($request->password) && $model->password = bcrypt($request->password);

        DB::beginTransaction();
        try {
            $model->save();
            $model->syncRoles($request->role_names);
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }

        $response = UserService::detail($model);
        return responder()->success($response);
    }

    /**
     * 用户详情
     */
    public function show(Request $request)
    {
        $request->validate([
            'id' => ['required', 'exists:users,id'],
        ], [
            'id.required' => '用户id不能为空',
            'id.exists' => '用户id不正确',
        ]);

        $response = UserService::detail($request->id);
        return responder()->success($response);
    }

    /**
     * 当前用户详情
     */
    public function info()
    {
        return UserService::detail();
    }

    /**
     * 用户列表
     */
    public function list(Request $request)
    {
        $query = User::query();
        if (!empty($request->id)) {
            $query->where(['id' => $request->id]);
        }
        if (!empty($request->phone)) {
            $query->where(['phone' => $request->phone]);
        }
        if (!empty($request->name)) {
            $query->where('name', 'like', "%{$request->name}%");
        }
        if (Auth::user()->district_id != District::CITY_ID) {
            $query->where(['district_id' => Auth::user()->district_id]);
        }
        $pageSize = isset($request->page_size) ? $request->page_size : 10;
        $response = $query->with(['roles', 'district'])->orderBy('id', 'desc')->paginate($pageSize);
        return responder()->success($response);
    }

    /**
     * 角色列表
     */
    public function roleList(Request $request)
    {
        $query = Role::query();
        if (!empty($request->type)) {
            $query->where(['type' => $request->type]);
        }
        $response = $query->orderBy('id', 'asc');
        return responder()->success($response);
    }

    /**
     * 登出
     */
    public function logout()
    {
        Auth::user()->tokens()->delete();
        return responder()->success();
    }

    private function checkRole($userDistrictId, $roleNames)
    {
        foreach ($roleNames as $roleName) {
            $role = Role::findByName($roleName);
            UserService::checkRoleType($userDistrictId, $role->type);
        }

        return true;
    }

    private function checkRole1($userDistrictId, $roleName, $userId = 0)
    {
        $role = Role::findByName($roleName);
        UserService::checkRoleType($userDistrictId, $role->type);

        if (in_array($roleName, ['市级审核员', '填报单位填报员', '填报单位审核员'])) {
            $query = User::query();
            $query->where(['district_id' => $userDistrictId]);
            if ($userId) {
                $query->where('id', '!=', $userId);
            }
            $userIds = $query->pluck('id')->all();
            $roleCount = User::with('roles')->whereIn('id', $userIds)->get()->filter(
                fn($user) => $user->roles->where('name', $roleName)->toArray()
            )->count();
            if ($roleCount) {
                throw new AppException('该角色已经存在');
            }
        }

        return true;
    }

    /**
     * 分配角色，测试用
     */
    public function assignRole(Request $request)
    {
        $userId = $request->user_id;
        $roleName = $request->role_name;
        $user = User::where(['id' => $userId])->first();
        $user->syncRoles($roleName);
        return responder()->success();
    }

    /**
     * 删除用户
     */
    public function delete(Request $request)
    {
        $user = Auth::user();
        $request->validate(
            [
                'id' => ['required',
                    Rule::exists('users', 'id')
                        ->where(function (Builder $query) use ($user) {
                            if ($user->district_id == District::CITY_ID) {
                                return $query->whereNull('deleted_at');
                            } else {
                                return $query->whereNull('deleted_at')->where(['district_id' => $user->district_id]);
                            }
                        }),
                ],
            ],
            [
                'id.required' => '用户id不能为空',
                'id.exists' => '不能删除该用户',
            ]);

        $model = User::where(['id' => $request->id])->first();
        $model->syncRoles([]);
        $model->delete();
        return responder()->success();
    }

    public function modifyPassword(Request $request)
    {
        $request->validate([
            'old_password' => ['required'],
            'password' => ['required', 'min:6'],
            'password_confirmation' => ['required', 'same:password'],
        ], [
            'old_password.required' => '旧密码不能为空',
            'password.required' => '新密码不能为空',
            'password.min' => '密码不能少于6位',
            'password_confirmation.required' => '确认密码不能为空',
            'password_confirmation.same' => '两次密码不一致',
        ]);

        $user = Auth::user();
        if (!Hash::check($request->old_password, $user->password)) {
            throw new AppException('旧密码错误');
        }

        $user->password = bcrypt($request->password);
        $user->save();
        $user->tokens()->delete();
        return responder()->success();
    }

    /**
     * 发送短信验证码
     */
    public function sendSmsCode(Request $request)
    {
        $sms = new Sms();
        $sms->sendSmsCode($request->phone);
        return responder()->success();
    }

    /**
     * 手机验证码登录
     */
    public function loginByCode(Request $request)
    {
        $request->validate([
            'phone' => ['required', 'regex:/^1[3456789]\d{9}$/'],
            'code' => ['required'],
        ], [
            'phone.required' => '手机号不能为空',
            'phone.regex' => '手机号格式不正确',
            'code.required' => '短信验证码不能为空',
        ]);

        Sms::checkCode($request->phone, $request->code);

        $user = User::where('phone', $request->phone)->first();
        if (!$user) {
            throw new AppException('用户不存在');
        }

        $response = UserService::detail($user);
        $response['token'] = $user->createToken('SanctumAuth')->plainTextToken;

        return responder()->success($response);
    }
}
